package com.greenzebras.geocache;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.greenzebras.geocache.cachedata.Cache;
import com.greenzebras.geocache.constant.GeocacheConstants;
import com.greenzebras.geocache.datastore.GeocacheCacheRequestResponseListener;
import com.greenzebras.geocache.datastore.persistence.GeocacheDataService;

public class GeocacheSearchActivity extends ListActivity implements
		GeocacheCacheRequestResponseListener {

	private List<Cache> cacheList;
	private CacheAdapter cacheListAdapter;
	private int DETAILS_REQUEST = 100;

	// Constructor
	public GeocacheSearchActivity() {
		cacheList = new ArrayList<Cache>();
	}

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.search);
		handleIntent(getIntent());

		// // Enable "type-to-search" functionality using the search dialog
		// setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL) ;

		ListView lv = getListView();
		lv.setTextFilterEnabled(true);

		lv.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {

				Cache clickedCache = ((CacheAdapter) getListAdapter())
						.getItem(position);

				// TEMPORARY PLACEHOLDER: Show a toast with the clicked Cache
				// info.
				// Toast.makeText(getApplicationContext(),
				// clickedCache.getName() + ": " +
				// clickedCache.getDescription(), Toast.LENGTH_SHORT).show();

				// Create the Detail intent
				Intent detailsIntent = new Intent(GeocacheSearchActivity.this,
						GeocacheDetailActivity.class);
				detailsIntent.putExtra(GeocacheDetailActivity.CACHE_TO_DISPLAY,
						clickedCache);
				startActivityForResult(detailsIntent, DETAILS_REQUEST);
			}
		});

		cacheListAdapter = new CacheAdapter(this, R.layout.search_item,
				cacheList);
		setListAdapter(cacheListAdapter);
	}

	@Override
	protected void onNewIntent(Intent intent) {
		setIntent(intent);
		handleIntent(intent);
	}

	private void handleIntent(Intent intent) {
		if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
			String query = intent.getStringExtra(SearchManager.QUERY);
			Log.i(getClass().getName(), "-- intent is ACTION_SEARCH, query="
					+ query);
			searchCacheByText(query);
		} else {
			Boolean search_form = (Boolean) getIntent().getExtras().get(
					"search_form");
			List<String> cacheTypeFilter = (List<String>) getIntent()
					.getExtras().get("cacheTypes");

			if (null == search_form) {
				Log.e(getClass().getName(),
						"Unhandled search request received.");
			}
			if (null == cacheTypeFilter) {
				Log.e(getClass().getName(), "-- cacheTypeFilter is null.");
				cacheTypeFilter = new ArrayList<String>();
			}

			Log.i(getClass().getName(),
					"-- cacheTypeFilter size()=" + cacheTypeFilter.size()
							+ ", " + cacheTypeFilter.toString());
			GeocacheDataService.INSTANCE.getCachesForTypes(this,
					cacheTypeFilter);
		}
	}

	private void searchCacheByText(String query) {
		GeocacheDataService.INSTANCE.getCachesByNameSimilarTo(this, query);
	}

	/*
	 * We need to provide a custom adapter in order to use a custom list item
	 * view.
	 */
	public class CacheAdapter extends ArrayAdapter<Cache> {

		public CacheAdapter(Context context, int textViewResourceId,
				List<Cache> objects) {
			super(context, textViewResourceId, objects);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			LayoutInflater inflater = getLayoutInflater();
			View item = inflater.inflate(R.layout.search_item, parent, false);

			Cache cacheItem = getItem(position);
			String cacheDescription = cacheItem.getDescription();
			((TextView) item.findViewById(R.id.item_name)).setText(cacheItem
					.getName());
			((TextView) item.findViewById(R.id.item_description))
					.setText(getTrimmedDescription(cacheDescription));
			((TextView) item.findViewById(R.id.item_type)).setText(cacheItem
					.getCacheType().toString());

			return item;
		}
	} // end class CacheAdapter

	@Override
	public void processCacheRequestResponse(Cache cache) {
		// TODO Auto-generated method stub

	}

	@Override
	public void processCachesRequestResponse(List<Cache> caches) {
		// Stash the new caches and update the listview.
		if (!caches.isEmpty()) {
			cacheList.clear();
			cacheList.addAll(caches);
			cacheListAdapter.notifyDataSetChanged();
		} else {
			// TODO - would be nice to display an empty result note, rather than
			// a Toast.
			// TEMPORARY PLACEHOLDER: Show a toast with the clicked Cache info.
			Toast.makeText(getApplicationContext(), "No results found!",
					Toast.LENGTH_SHORT).show();
			finish();
		}
	}

	private String getTrimmedDescription(String cacheDescription) {
		int maxLength = GeocacheConstants.DESCRIPTION_TEXT_MAX_LENGTH;
		if (null != cacheDescription && !cacheDescription.isEmpty()
				&& cacheDescription.length() > maxLength) {
			return cacheDescription.substring(0, maxLength)
					+ GeocacheConstants.MORE_TEXT;
		}
		return cacheDescription;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if (DETAILS_REQUEST == requestCode) {
			if (RESULT_OK == resultCode) {
				// refresh the cache data, and the displayed cache data.
				if (data.hasExtra(GeocacheConstants.UPDATED_CACHE)) {
					Cache updatedCache = (Cache) data.getExtras().get(
							GeocacheConstants.UPDATED_CACHE);
					for (Cache cache : cacheList) {
						if (cache.getID().equals(updatedCache.getID())) {
							cache.copy(updatedCache);
						}
					}
					
					cacheListAdapter.notifyDataSetChanged();
				} else {
					Log.e(getClass().getName(),
							"Invalid Intent result returned to Detail activity for EDIT_CACHE_REQUEST.");
				}
			}
		}
	}
} // end class GeocacheSearchActivity
